package cn.net.autocode.platform.workflow;

import cn.hutool.core.util.StrUtil;
import cn.net.autocode.core.bean.ResultT;
import cn.net.autocode.core.utils.UserThreadLocalUtils;
import cn.net.autocode.dbManager.Dao;
import cn.net.autocode.dbManager.IdWorker;
import cn.net.autocode.platform.workflow.service.WorkflowServ;
import cn.net.autocode.platform.workflow.vo.Workflow;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;

@RestController("platformWorkflowCtrl")
@RequestMapping("/platform/workflow")
public class WorkflowCtrl {

    private final Dao dao;

    private final WorkflowServ workflowServ;

    public WorkflowCtrl(Dao dao, WorkflowServ workflowServ) {
        this.dao = dao;
        this.workflowServ = workflowServ;
    }

    //1、获取操作名称、下一步是否会签、是否原因必填
    @RequestMapping("stepInfo")
    public ResultT stepInfo(@RequestBody JSONObject param){
        String wfCode = param.getString("wfCode");
        String stepCode = param.getString("stepCode");
        if(StrUtil.isBlank(wfCode)||StrUtil.isBlank(stepCode)){
            return ResultT.fail("传递参数wfCode、stepCode不能为空");
        }
        //获取操作信息
        JSONObject json = new JSONObject();
        json.put("username", UserThreadLocalUtils.getUserName());
        //判断是否需要密码确认
        JSONObject step = dao.queryJSON("select * from autocode_wf_step where wf_code=? and step_code=?",wfCode,stepCode);
        if("Y".equals(step.getString("esigPassword"))){
            json.put("esigPassword","Y");
        }else{
            json.put("esigPassword","N");
        }

        JSONArray array = dao.queryJSONArray("select action_code value,action_name label,require_comment from autocode_wf_step_actions where wf_code=? and step_code=? order by sort_no",param.getString("wfCode"),param.getString("stepCode"));
        if (!array.isEmpty()){
            json.put("actionCode",array.getJSONObject(0).getString("value"));
        }

        return ResultT.success(json);
    }

    //1、获取操作名称、下一步是否会签、是否原因必填
    @RequestMapping("wfRecord")
    public ResultT wfRecord(@RequestBody JSONObject param){
        String wfCode = param.getString("wfCode");
        String busiId = param.getString("busiId");
        String sql="select t2.* from autocode_wf_record t1,autocode_wf_record_step t2 where t1.id=t2.wf_record_id and t1.wf_code=? and busi_id=? order by from_time";
        JSONArray array = dao.queryJSONArray(sql,wfCode,busiId);
        return ResultT.success(array);
    }

    //1、提交到下一步
    @RequestMapping("submit")
    @Transactional
    public ResultT submit(@RequestBody JSONObject param){
        Workflow workflow = new Workflow();
        //信息校验
        String validateMsg = workflowServ.validate(param,workflow);
        if(!"success".equals(validateMsg)){
            return ResultT.fail(validateMsg);
        }

        //获取校验信息
        workflowServ.before(workflow);
        workflowServ.action(workflow,"before");
        JSONArray nextSteps = workflowServ.after(workflow);
        workflowServ.action(workflow,"after");
        return ResultT.success(nextSteps);
    }

    @RequestMapping("cancel")
    @Transactional
    public ResultT cancel(@RequestBody JSONObject param){
        Workflow workflow = new Workflow();
        //信息校验
        String validateMsg = workflowServ.cancelValidate(param,workflow);
        if(!"success".equals(validateMsg)){
            return ResultT.fail(validateMsg);
        }
        //获取校验信息
        workflowServ.cancelDeal(workflow,"before");
        workflowServ.cancel(workflow);
        workflowServ.cancelDeal(workflow,"after");
        return ResultT.success();
    }

    @RequestMapping("saveWfStep")
    public ResultT saveWfStep(@RequestBody JSONObject param){
        String id = param.getString("id");
        String auditOrgan = param.getString("auditOrgan");
        if(auditOrgan==null || auditOrgan.isBlank()){
            auditOrgan = "default";
            param.put("auditOrgan",auditOrgan);
        }

        if(StrUtil.isBlank(id)){
            id = IdWorker.ulid();
            param.put("id",id);
            dao.createJSON(param,"autocode_wf_step");
        }else{
            //判定组织机构是否发送变化
            String organ = dao.queryValue("select audit_organ from autocode_wf_step where id=?",String.class,id);
            if(!auditOrgan.equals(organ)){
                dao.executeUpdate("delete from autocode_wf_step_users where wf_step_id=?",id);
            }
            dao.updateJSON(param,"autocode_wf_step");
        }

        return ResultT.success(param);
    }

    @RequestMapping("organUser")
    public ResultT orgUser(@RequestBody JSONObject param){
        String wfStepId = param.getString("wfStepId");
        String organCode = dao.queryValue("select audit_organ from autocode_wf_step where id=?",String.class,wfStepId);
        if ("default".equals(organCode) || organCode==null || organCode.isBlank()){
            organCode = UserThreadLocalUtils.getOrgCode();
        }

        String sql = "select t1.* from sys_users t1,sys_organ_users t2 where t1.username=t2.username and t2.org_code=?";
        JSONArray users = dao.queryJSONArray(sql,organCode);
        return ResultT.success(users);
    }

    @RequestMapping("saveWfStepUser")
    @Transactional
    public ResultT saveWfStepUser(@RequestBody JSONObject param){
        String wfStepId = param.getString("wfStepId");
        JSONArray users = param.getJSONArray("users");
        List<String> userNames = new ArrayList<>();
        for (int i = 0; i < users.size(); i++) {
            userNames.add(users.getJSONObject(i).getString("username"));
        }
        if (userNames.isEmpty()){
            dao.executeUpdate("delete from autocode_wf_step_users where wf_step_id=? and audit_type='user'",wfStepId);
        }else{
            dao.executeUpdate("delete from autocode_wf_step_users where wf_step_id=? and audit_type='user' and username not in (?)",wfStepId,userNames);
            //查询已经存在的username
            List<String> existUsers = dao.queryListValue("select username from autocode_wf_step_users where wf_step_id=? and audit_type='user'",String.class,wfStepId);
            for (int i = 0; i < users.size(); i++) {
                String username = users.getJSONObject(i).getString("username");
                String fullname = users.getJSONObject(i).getString("fullname");
                if (!existUsers.contains(username)){
                    dao.executeUpdate("insert into autocode_wf_step_users(id,wf_step_id,audit_type,username,fullname) values(?,?,?,?,?)", IdWorker.ulid(),wfStepId,"user",username,fullname);
                }
            }
        }
        return ResultT.success();
    }


    @RequestMapping("organRole")
    public ResultT organRole(@RequestBody JSONObject param){
        String wfStepId = param.getString("wfStepId");
        String organCode = dao.queryValue("select audit_organ from autocode_wf_step where id=?",String.class,wfStepId);
        if ("default".equals(organCode) || organCode==null || organCode.isBlank()){
            organCode = UserThreadLocalUtils.getOrgCode();
        }

        String sql = "select * from sys_roles where org_code=?";
        JSONArray users = dao.queryJSONArray(sql,organCode);
        return ResultT.success(users);
    }

    @RequestMapping("saveWfStepRole")
    @Transactional
    public ResultT saveWfStepRole(@RequestBody JSONObject param){
        String wfStepId = param.getString("wfStepId");
        JSONArray roles = param.getJSONArray("roles");
        List<String> roleIds = new ArrayList<>();
        for (int i = 0; i < roles.size(); i++) {
            roleIds.add(roles.getJSONObject(i).getString("id"));
        }
        if (roleIds.isEmpty()){
            dao.executeUpdate("delete from autocode_wf_step_users where wf_step_id=? and audit_type='role'",wfStepId);
        }else{
            dao.executeUpdate("delete from autocode_wf_step_users where wf_step_id=? and audit_type='role' and role_id not in (?)",wfStepId,roleIds);
            //查询已经存在的username
            List<String> existRoles = dao.queryListValue("select role_id from autocode_wf_step_users where wf_step_id=? and audit_type='role'",String.class,wfStepId);
            for (int i = 0; i < roles.size(); i++) {
                String roleId = roles.getJSONObject(i).getString("id");
                String fullname = roles.getJSONObject(i).getString("label");
                if (!existRoles.contains(roleId)){
                    dao.executeUpdate("insert into autocode_wf_step_users(id,wf_step_id,audit_type,role_id,fullname) values(?,?,?,?,?)", IdWorker.ulid(),wfStepId,"role",roleId,fullname);
                }
            }
        }
        return ResultT.success();
    }

    @RequestMapping("organUgroup")
    public ResultT organUgroup(@RequestBody JSONObject param){
        String wfStepId = param.getString("wfStepId");
        String organCode = dao.queryValue("select audit_organ from autocode_wf_step where id=?",String.class,wfStepId);
        if ("default".equals(organCode) || organCode==null || organCode.isBlank()){
            organCode = UserThreadLocalUtils.getOrgCode();
        }

        String sql = "select * from sys_ugroup where org_code=?";
        JSONArray ugroups = dao.queryJSONArray(sql,organCode);
        return ResultT.success(ugroups);
    }

    @RequestMapping("saveWfStepUgroup")
    @Transactional
    public ResultT saveWfStepUgroup(@RequestBody JSONObject param){
        String wfStepId = param.getString("wfStepId");
        JSONArray groups = param.getJSONArray("groups");
        List<String> groupIds = new ArrayList<>();
        for (int i = 0; i < groups.size(); i++) {
            groupIds.add(groups.getJSONObject(i).getString("id"));
        }
        if (groupIds.isEmpty()){
            dao.executeUpdate("delete from autocode_wf_step_users where wf_step_id=? and audit_type='ugroup'",wfStepId);
        }else{
            dao.executeUpdate("delete from autocode_wf_step_users where wf_step_id=? and audit_type='ugroup' and role_id not in (?)",wfStepId,groupIds);
            //查询已经存在的username
            List<String> existGroups = dao.queryListValue("select role_id from autocode_wf_step_users where wf_step_id=? and audit_type='ugroup'",String.class,wfStepId);
            for (int i = 0; i < groups.size(); i++) {
                String groupId = groups.getJSONObject(i).getString("id");
                String fullname = groups.getJSONObject(i).getString("name");
                if (!existGroups.contains(groupId)){
                    dao.executeUpdate("insert into autocode_wf_step_users(id,wf_step_id,audit_type,role_id,fullname) values(?,?,?,?,?)", IdWorker.ulid(),wfStepId,"ugroup",groupId,fullname);
                }
            }
        }
        return ResultT.success();
    }


    @RequestMapping("defaultAction")
    @Transactional
    public ResultT defaultAction(@RequestBody JSONObject param){
        String wfCode = param.getString("wfCode");
        String stepCode = param.getString("stepCode");
        //查询所有环节
        JSONArray steps = dao.queryJSONArray("select * from autocode_wf_step where wf_code=? order by sort_no",wfCode);

        String sql = "select * from autocode_wf_step_actions where wf_code=? and step_code=? and action_code=?";

        //查询submit是否存在
        JSONObject submitAction = dao.queryJSON(sql,wfCode,stepCode,"submit");
        if (submitAction==null || submitAction.isEmpty()){
            submitAction = new JSONObject();

            submitAction.put("id",IdWorker.ulid());
            submitAction.put("wfCode",wfCode);
            submitAction.put("stepCode",stepCode);
            submitAction.put("actionCode","submit");
            submitAction.put("actionName","提交");
            submitAction.put("requireComment","N");
            submitAction.put("isreject","N");
            submitAction.put("sortNo",1);

            boolean current = false;
            String nextStep = null;
            for (int i = 0; i < steps.size(); i++) {
                JSONObject step = steps.getJSONObject(i);
                if (current){
                    nextStep = step.getString("stepCode");
                    break;
                }
                String stepCode1 = step.getString("stepCode");
                if (stepCode1.equals(stepCode)){
                    current = true;
                    submitAction.put("wfStepId",step.getString("id"));
                }
            }
            if (nextStep == null){
                nextStep = stepCode;
            }
            submitAction.put("toStepcode",nextStep);
            dao.createJSON(submitAction,"autocode_wf_step_actions");
        }

        //查询reject是否存在
        JSONObject rejectAction = dao.queryJSON(sql,wfCode,stepCode,"reject");
        if (rejectAction==null || rejectAction.isEmpty()){
            rejectAction = new JSONObject();

            rejectAction.put("id",IdWorker.ulid());
            rejectAction.put("wfCode",wfCode);
            rejectAction.put("stepCode",stepCode);
            rejectAction.put("actionCode","reject");
            rejectAction.put("actionName","退回");
            rejectAction.put("requireComment","Y");
            rejectAction.put("isreject","Y");
            rejectAction.put("sortNo",2);

            String nextStep;
            if(steps.size()>0){
                JSONObject step = steps.getJSONObject(0);
                nextStep = step.getString("stepCode");
                if(!nextStep.equals(stepCode)){
                    rejectAction.put("toStepcode",nextStep);
                    dao.createJSON(rejectAction,"autocode_wf_step_actions");
                }
            }

        }

        return ResultT.success();
    }


    @RequestMapping("copy")
    @Transactional
    public ResultT copy(@RequestBody JSONObject param){
        String oldId = param.getString("id");

        String newId = IdWorker.ulid();
        String newWfCode = param.getString("wfCode");
        //判定工作流是否存
        int num = dao.queryValue("select count(*) from autocode_wf where wf_code=?",Integer.class,newWfCode);
        if (num>0){
            return ResultT.fail(newWfCode+"已存在！");
        }

        param.put("id",newId);
        //添加流程信息
        dao.createJSON(param,"autocode_wf");

        //复制工作流步骤
        JSONArray steps = dao.queryJSONArray("select * from autocode_wf_step where wf_id=? order by sort_no",oldId);
        for (int i = 0; i < steps.size(); i++) {
            JSONObject step = steps.getJSONObject(i);
            String oldStepId = step.getString("id");
            String newStepId = IdWorker.ulid();
            step.put("id",newStepId);
            step.put("wfCode",newWfCode);
            step.put("wfId",newId);
            dao.createJSON(step,"autocode_wf_step");

            //获取操作人或角色
            JSONArray stepUsers = dao.queryJSONArray("select * from autocode_wf_step_users where wf_step_id=?",oldStepId);
            for (int j = 0; j < stepUsers.size(); j++) {
                JSONObject stepUser = stepUsers.getJSONObject(j);
                stepUser.put("id",IdWorker.ulid());
                stepUser.put("wfStepId",newStepId);
                dao.createJSON(stepUser,"autocode_wf_step_users");
            }

        }
        //或者执行动作
        String oldWfCode = dao.queryValue("select wf_code from autocode_wf where id=?",String.class,oldId);
        JSONArray actions = dao.queryJSONArray("select * from autocode_wf_step_actions where wf_code=?",oldWfCode);
        for(int i=0;i<actions.size();i++){
            JSONObject action = actions.getJSONObject(i);
            action.put("id",IdWorker.ulid());
            action.put("wfCode",newWfCode);
            dao.createJSON(action,"autocode_wf_step_actions");
        }

        //处理规则复制待完善


        return ResultT.success(param);
    }
}
